package com.promise.jokerdream.work.penguin

import com.promise.jokerdream.database.entity.AbyssGameConfigEntity
import com.promise.jokerdream.manager.ExecutionHistoryManager
import com.promise.jokerdream.repository.GameApi
import com.promise.jokerdream.utils.AppContext
import com.promise.jokerdream.work.BaseWork
import com.promise.jokerdream.work.WorkResult

// 深渊工作
class AbyssWork(
    private val config: AbyssGameConfigEntity,
    uin: String
): BaseWork(uin) {

    private val gameApi = GameApi.Companion.getInstance()
    private val historyManager by lazy { ExecutionHistoryManager.Companion.getInstance(AppContext.get()) }

    override val name: String
        get() = "深渊"

    override suspend fun executeWork(): WorkResult {
        return try {
            // 1. 先领取许愿点
            if (config.wishPointsEnabled) {
                executeWishPoints()
            }

            // 如果不需要兑换次数和挑战，直接返回成功
            if (!config.exchangeTimesEnabled && !config.challengeEnabled) {
                return WorkResult.Success
            }

            // 2. 查询深渊状态，根据canBuyTimes决定兑换挑战次数
            val queryResult1 = gameApi.queryAbyssTide()
            queryResult1.fold(
                onSuccess = { response ->
                    if (config.exchangeTimesEnabled && response.canBuyTimes > 0) {
                        repeat(response.canBuyTimes) {
                            executeExchangeTimes()
                        }
                    }

                    // 如果不需要挑战，直接返回成功
                    if (!config.challengeEnabled) {
                        return WorkResult.Success
                    }

                    // 3. 再查一次深渊状态，根据accessTime决定挑战多少次
                    val queryResult2 = gameApi.queryAbyssTide()
                    queryResult2.fold(
                        onSuccess = { finalResponse ->
                            if (finalResponse.accessTime > 0) {
                                executeMultipleChallenges(finalResponse.accessTime)
                            } else {
                                WorkResult.Success
                            }
                        },
                        onFailure = { exception ->
                            WorkResult.Failure(exception, exception.message)
                        }
                    )
                },
                onFailure = { exception ->
                    WorkResult.Failure(exception, exception.message)
                }
            )
        } catch (e: Exception) {
            WorkResult.Failure(e, e.message)
        }
    }

    /**
     * 执行领取许愿点
     */
    private suspend fun executeWishPoints(): WorkResult {
        return try {
            // 先查询许愿点信息
            val queryResult = gameApi.queryAbyssTideGift()
            queryResult.fold(
                onSuccess = { response ->
                    if (response.canGetGift != 0) {
                        // 可以领取许愿点
                        val getResult = gameApi.getAbyssWishPoints()
                        getResult.fold(
                            onSuccess = { getResponse ->
                                historyManager.addHistory(name, getResponse.getDescription())
                                WorkResult.Success
                            },
                            onFailure = { exception ->
                                historyManager.addHistory(name, exception.message)
                                WorkResult.Failure(exception, exception.message)
                            }
                        )
                    } else {
                        // 不可领取许愿点
                        WorkResult.Success
                    }
                },
                onFailure = { exception ->
                    historyManager.addHistory(name, exception.message)
                    WorkResult.Failure(exception, exception.message)
                }
            )
        } catch (e: Exception) {
            historyManager.addHistory(name, e.message)
            WorkResult.Failure(e, e.message)
        }
    }

    /**
     * 执行兑换挑战次数
     */
    private suspend fun executeExchangeTimes(): WorkResult {
        return try {
            val result = gameApi.addAbyssAccess()
            result.fold(
                onSuccess = { response ->
                    historyManager.addHistory(name, response.getDescription())
                    WorkResult.Success
                },
                onFailure = { exception ->
                    historyManager.addHistory(name, exception.message)
                    WorkResult.Failure(exception, exception.message)
                }
            )
        } catch (e: Exception) {
            WorkResult.Failure(e, e.message)
        }
    }

    /**
     * 执行多次挑战
     * @param times 挑战次数
     */
    private suspend fun executeMultipleChallenges(times: Int): WorkResult {

        repeat(times) {
            val result = executeSingleChallenge()
            when (result) {
                is WorkResult.Success -> {}
                is WorkResult.Failure -> {
                    historyManager.addHistory(name, result.message)
                }
                is WorkResult.Cancelled -> {
                    historyManager.addHistory(name, "挑战被取消")
                }
            }
        }

        return WorkResult.Success
    }

    /**
     * 执行单次挑战深渊Boss
     */
    private suspend fun executeSingleChallenge(): WorkResult {
        return try {
            // 1. 进入深渊挑战
            val abyssId = config.getSelectedAbyssId()
            if (abyssId == null) {
                return WorkResult.Failure(Exception("深渊ID解析失败"), "深渊ID解析失败")
            }
            val enterResult = gameApi.enterAbyss(abyssId)
            enterResult.fold(
                onSuccess = { response ->
                    // 2. 开始挑战循环
                    executeChallengeLoop()
                },
                onFailure = { exception ->
                    historyManager.addHistory(name, exception.message)
                    WorkResult.Failure(exception, exception.message)
                }
            )
        } catch (e: Exception) {
            WorkResult.Failure(e, e.message)
        }
    }

    /**
     * 执行挑战循环
     * 状态1：继续挑战
     * 状态2：死亡，尝试复活
     * 状态3：通过，结束挑战
     */
    private suspend fun executeChallengeLoop(): WorkResult {
        var currentStatus = 1 // 初始状态为1（未开始）

        while (currentStatus == 1) {
            // 开始挑战
            val fightResult = gameApi.beginAbyssFight()
            fightResult.fold(
                onSuccess = { fightResponse ->
                    historyManager.addHistory(name, fightResponse.getDescription())
                    currentStatus = fightResponse.fightStatus

                    when (currentStatus) {
                        1 -> {
                            // 状态1：继续挑战，循环继续
                        }
                        2 -> {
                            // 状态2：死亡，检查是否勾选复活
                            if (config.reviveEnabled) {
                                val reviveResult = gameApi.reviveAbyss()
                                reviveResult.fold(
                                    onSuccess = { reviveResponse ->
                                        historyManager.addHistory(name, reviveResponse.getDescription())
                                        // 复活后检查战斗状态
                                        when (reviveResponse.fightStatus) {
                                            1 -> {
                                                // 状态1：复活成功，继续挑战
                                                currentStatus = 1
                                            }
                                            2 -> {
                                                // 状态2：复活后仍然死亡，结束挑战
                                                val endResult = gameApi.endAbyss()
                                                endResult.fold(
                                                    onSuccess = { endResponse ->
                                                        historyManager.addHistory(name, endResponse.getDescription())
                                                    },
                                                    onFailure = { endException ->
                                                        historyManager.addHistory(name, endException.message)
                                                    }
                                                )
                                                return WorkResult.Success
                                            }
                                            3 -> {
                                                currentStatus = 3
                                            }
                                        }
                                    },
                                    onFailure = { exception ->
                                        historyManager.addHistory(name, exception.message)
                                        return WorkResult.Failure(exception, exception.message)
                                    }
                                )
                            } else {
                                // 未勾选复活，直接结束挑战
                                val endResult = gameApi.endAbyss()
                                endResult.fold(
                                    onSuccess = { endResponse ->
                                        historyManager.addHistory(name, endResponse.getDescription())
                                    },
                                    onFailure = { exception ->
                                        historyManager.addHistory(name, exception.message)
                                    }
                                )
                                return WorkResult.Success
                            }
                        }
                        3 -> {
                            // 状态3：通过，结束挑战
                            val endResult = gameApi.endAbyss()
                            endResult.fold(
                                onSuccess = { endResponse ->
                                    historyManager.addHistory(name, endResponse.getDescription())
                                },
                                onFailure = { exception ->
                                    historyManager.addHistory(name, exception.message)
                                }
                            )
                        }
                    }
                },
                onFailure = { exception ->
                    historyManager.addHistory(name, exception.message)
                    return WorkResult.Failure(exception, exception.message)
                }
            )
        }

        return WorkResult.Success
    }
}